package com.dly.hope.servce;

import com.dly.hope.workflow.ConditionInfo;
import com.dly.hope.workflow.NodeInfo;
import com.dly.hope.workflow.ProcessInfo;
import com.dly.hope.workflow.ProcessInstance;
import com.dly.hope.workflow.dto.ApprRecordDTO;
import com.dly.hope.workflow.dto.WorkflowData;
import com.dly.hope.workflow.ro.ConditionInfoRO;
import com.dly.hope.workflow.ro.NodeInfoRO;
import com.dly.hope.workflow.ro.NodeRolesRO;
import com.dly.hope.workflow.ro.ProcessInfoRO;
import com.dly.hope.workflow.type.ProcessEnum;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * @author DBC20220821
 */
public interface WorkflowService {

    /**
     * @Description: 创建审批流实例
     * @Param: [processEnum, sponsorId, expireDays, context, callback]
     * @return: void
     * @Author: Danny Chen
     * @Date: 2022/1/19
     */
    @Transactional
    void createProcessInstance(ProcessEnum processEnum,
                               String sponsorId,
                               Integer expireDays,
                               Map<String, Object> context,
                               Consumer<WorkflowData> callback);

    /**
     * @Description: 更新节点实例 - 当操作员点击审批通过或驳回的时候需要调用此方法
     * @Param: [nodeId, approverId, apprResult, suggestion, callback]
     * @return: void
     * @Author: Danny Chen
     * @Date: 2022/1/19
     */
    @Transactional
    void approval(@NotNull String nodeId,
                  String approverId,
                  String apprResult,
                  String suggestion,
                  String remark,
                  Consumer<WorkflowData> callback);

    /**
     * @Description: 重新发起审批流程，当单据被拒绝且发起人修改后重新提交时需要调用此方法重新发起流程
     * @Param: [processInstanceId, context, callback]
     * @return: void
     * @Author: Danny Chen
     * @Date: 2022/1/20
     */
    @Transactional
    void restartProcessInstance(@NotNull String processInstanceId,
                                String sponsorId,
                                Map<String, Object> context,
                                Consumer<WorkflowData> callback);

    /**
     * @Description: 根据流程实例ID查询审批履历
     * @Param: [processInstanceId]
     * @return: java.util.List<com.dragonbravo.magicfund.model.dto.ApprRecordDTO>
     * @Author: Danny Chen
     * @Date: 2022/1/23
     */
    List<ApprRecordDTO> getApprRecords(@NotNull String processInstanceId);

    /**
     * @Description: 根据节点实例ID查询审批履历 (某些业务表没有存流程实例ID可以用此方法)
     * @Param: [processInstanceId]
     * @return: java.util.List<com.dragonbravo.magicfund.model.dto.ApprRecordDTO>
     * @Author: Danny Chen
     * @Date: 2022/1/23
     */
    List<ApprRecordDTO> getApprRecordsByNodeInstanceId(String nodeInstanceId);

//    /**
//     * @Description: 用户登录ERP的时候，根据角色查询所有待审批的条据统计
//     * @Param: [roleId]
//     * @return: java.util.List<com.dragonbravo.magicfund.model.dto.ApprCountDTO>
//     * @Author: Danny Chen
//     * @Date: 2022/1/23
//     */
//    List<ApprCountDTO> getPendingNodesByRoleId(@NotNull String userId, @NotNull String roleId);



    /**
     * @Description: 创建/更新审批流程定义 - 仅开发或IT维护人员使用
     * @Param: [processInfoRO]
     * @return: com.dragonbravo.magicfund.model.workflow.ProcessInfo
     * @Author: Danny Chen
     * @Date: 2022/1/19
     */
    ProcessInfo saveProcessInfo(ProcessInfoRO processInfoRO);

    /**
     * @Description: 创建/更新审批流程节点定义 - 仅开发或IT维护人员使用
     * @Param: [nodeInfoRO]
     * @return: com.dragonbravo.magicfund.model.workflow.NodeInfo
     * @Author: Danny Chen
     * @Date: 2022/1/19
     */
    NodeInfo saveNodeInfo(NodeInfoRO nodeInfoRO);

    /**
     * @Description: 创建/更新审批流程条件定义 - 仅开发或IT维护人员使用
     * @Param: [conditionInfoRO]
     * @return: com.dragonbravo.magicfund.model.workflow.ConditionInfo
     * @Author: Danny Chen
     * @Date: 2022/1/19
     */
    ConditionInfo saveConditionInfo(ConditionInfoRO conditionInfoRO);

    /**
     * @Description: 给节点添加审批角色列表 - 仅开发或IT维护人员使用
     * @Param: [nodeRolesRO]
     * @return: void
     * @Author: Danny Chen
     * @Date: 2022/1/23
     */
    void saveNodeRoles(NodeRolesRO nodeRolesRO);

    /**
     * @author: yonghua.huang
     * @description: 为了兼容售前检测奇奇怪怪的问题所重载的方法，不生成提交记录
     * @param: [processInstanceId, sponsorId, context, callback]
     * @return: void
     * @date 2022/7/1 10:34
     */
    @Transactional
    void restartProcessInstanceWithNoStart(@NotNull String processInstanceId,
                                           String sponsorId,
                                           Map<String, Object> context,
                                           Consumer<WorkflowData> callback);

    /**
     * @Description: 创建审批流实例,为了兼容售前检测奇奇怪怪的问题所重载的方法，不生成提交记录
     * @Param: [processEnum, sponsorId, expireDays, context, callback]
     * @return: void
     * @Author: Danny Chen
     * @Date: 2022/1/19
     */
    @Transactional
    void createProcessInstanceWithNoStart(ProcessEnum processEnum,
                                          String sponsorId,
                                          Integer expireDays,
                                          Map<String, Object> context,
                                          Consumer<WorkflowData> callback);

    /**
     * @Description: 创建发起人节点（虚拟开始节点）
     * 业务场景：为了兼容售前奇奇怪怪的问题所以拎出来public
     * 在每次新建、或驳回后重新发起审批流程的时候，都需要记录最新的发起人（提交人），显示在审批履历中，
     * 因此每次新建或重新发起流程的时候调用下面这个方法可以添加一个虚拟的节点信息记录发起人，显示在履历中。
     * @Param: [processInstanceId]
     * @Author: Danny Chen
     * @Date: 2022/6/16
     */
    void createSponsorNodeInstanceWithPreSale(ProcessInstance processInstance, String sponsorUserId);


}
